<template>
  <div>
    <!--  三级列表-->
    <Category :disabled="isAttrOrAddUpdate"/>
    <!--    三级列表晒选出来的属性列表数据-->
    <el-card v-if="isAttrOrAddUpdate" style="margin-top: 30px">
      <template #header>
        <el-button type="primary" icon="ele-Plus" @click="addAttrItem" :disabled="!categoryList3Id">添加属性</el-button>
      </template>
      <el-table :data="AttrList" border style="width: 100%">
        <el-table-column align="center" type="index" label="序号" width="80"/>
        <el-table-column prop="attrName" label="属性名称" width="180"></el-table-column>
        <el-table-column prop="attrValueList" label="属性值名称列表">
          <template #default="{row}">
            <el-tag style="margin-right:10px " class="ml-2" type="danger" v-for="item in row.attrValueList"
                    :key="item.id">
              {{ item.valueName }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column align="center" label="操作" width="180">
          <template #default="{row}">
            <el-button title="修改" @click="fixAttrItem(row)" type="warning" size="small"
                       icon="ele-Edit"></el-button>
            <el-popconfirm title="确定删除?" @confirm="removeAttr(row.id)">
              <template #reference>
                <el-button title="删除" type="danger" size="small" icon="ele-Delete"></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!--    添加功能和修改功能的静态-->
    <el-card v-else style="margin-top: 30px">
      <el-form label-width="80px" :inline="true">
        <el-form-item label="属性名">
          <el-input v-model="AttrItem.attrName" size="small" clearable/>
        </el-form-item>
      </el-form>
      <div>
        <el-button type="primary" @click="addAttrValueItem" :disabled="!AttrItem.attrName">添加属性值</el-button>
        <el-button @click="isAttrOrAddUpdate=true">取消</el-button>
      </div>
      <el-table :data="AttrItem.attrValueList" border style="width: 100%;margin: 20px 0">
        <el-table-column type="index" label="序号" width="80"/>
        <el-table-column prop="valueName" label="属性值名称">
          <template #default="{row,$index}">
            <el-input ref="inputEle" @blur='isInput(row,$index)' v-if="row.isEdit" v-model="row.valueName"></el-input>
            <span @click="isSpan(row)" v-else>{{ row.valueName }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80">
          <template #default="{row,$index}">
            <el-button type='danger' @click="removeAttrValueItem($index)" size="small">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div>
        <el-button type="primary" @click="save"
                   :disabled="AttrItem.attrName == '' || AttrItem.attrValueList.length === 0">保存
        </el-button>
        <el-button @click="isAttrOrAddUpdate=true">返回</el-button>
      </div>
    </el-card>
  </div>
</template>

<script lang="ts">
import {defineComponent} from "vue";

export default defineComponent({
  name: "Attr",
});
</script>

<script setup lang="ts">
import useCategoryStore from "@/stores/category";
import {storeToRefs} from "pinia";
import {nextTick, ref, watch} from "vue";
import {
  type AttrItemType,
  type AttrListType,
  type AttrValueItem,
  reqAddOrUpdateAttrInfoListAsync,
  reqAttrInfoListAsync, reqDeleteAttrAsync
} from "@/api/attr";
import {ElMessage} from "element-plus";
import {cloneDeep} from 'lodash'

// 得到 categoryStore 对象
const categoryStore = useCategoryStore()

// 解构 三级列表的所有id
const {categoryList1Id, categoryList2Id, categoryList3Id} = storeToRefs(categoryStore)

// 保存 属性数据列表
const AttrList = ref<AttrListType>([])

// 获取属性数据列表
const getAttrList = async () => {
  try {
    const re = await reqAttrInfoListAsync(
        categoryList1Id.value as number,
        categoryList2Id.value as number,
        categoryList3Id.value as number
    )
    AttrList.value = re
  } catch (e: any) {
    ElMessage.error(e.message)
  }
}

// 监听 categoryList3Id 当他有值  就代表 三级列表查询条件 齐全
watch(categoryList3Id, (newVal) => {
  // 最新的categoryList3Id值 newVal 为null 不发请求
  if (!newVal) return

  // 获取属性数据列表
  getAttrList()
})

// 属性数据列表和添加/修改组件 只会显示一个  默认属性数据列表
const isAttrOrAddUpdate = ref(true)

// 收集添加属性获取修改属性的数据
const AttrItem = ref<AttrItemType>({
  attrName: '',  // 收集的当前的平台属性名
  attrValueList: [],  // 收集的当前属性的属性值列表
  categoryId: categoryList3Id.value as number,  // 固定的当前的category3Id的值  因为我们只能在 3id下面添加
  categoryLevel: 3,  // 固定的3
})

// 添加属性
const addAttrItem = () => {
  // 显示添加组件
  isAttrOrAddUpdate.value = false

  // 清除上一次的属性
  AttrItem.value = {
    attrName: '',  // 收集的当前的平台属性名
    attrValueList: [],  // 收集的当前属性的属性值列表
    categoryId: categoryList3Id.value as number,  // 固定的当前的category3Id的值  因为我们只能在 3id下面添加
    categoryLevel: 3,  // 固定的3
  }
}

// 添加属性值
const addAttrValueItem = () => {
  // 添加的属性值的固定格式
  const attrValueItem: AttrValueItem = {
    attrId: AttrItem.value.id,     // 是固定的 当前所在属性的id(新增的时候,属性没有id,没有关系,将来添加到服务端就有了)
    valueName: '',   // 双向数据绑定了 可以收集到 属性值
    isEdit: true   //新增一个属性,代表当前是编辑模式(添加属性值的时候 input标签) 还是查看模式(修改属性值的时候 span标签) 并且两种模式可以相互切换
  }

  // 添加属性值
  AttrItem.value.attrValueList.push(attrValueItem)

  // 页面更新的时候 虚拟DOM渲染成真实DOM的过程是异步的  所以想要操作DOM 必须等待真实DOM 渲染完成
  nextTick(() => {  // 真实DOM 渲染完成 回调函数执行
    inputEle.value.focus()  // 自动获取input 焦点
  })
}

// 修改属性
const fixAttrItem = (row: AttrItemType) => {
  // 显示修改组件
  isAttrOrAddUpdate.value = false;

  // 将原修改数据显示在修改组件
  AttrItem.value = cloneDeep(row);   // row对象  需要拷贝

  // 将修改数据 设计成 编辑模式
  AttrItem.value.attrValueList = AttrItem.value.attrValueList.map(item => {
    item.isEdit = false;
    return item
  })
}

// 获取input组件的 DOM元素  控制编辑模式的时候自动获取焦点
const inputEle = ref()

// input组件 失焦的时候 将编辑模式改为查看模式
const isInput = (row: AttrValueItem, index: number) => {
  row.isEdit = false;

  // 此时判断是否有值 无值 剔除
  if (!row.valueName) return AttrItem.value.attrValueList.splice(index, 1)

  // 继续判断添加的属性值是否重复 重复剔除
  const isRepetition = AttrItem.value.attrValueList.some(item => {
    if (item !== row) {  // 不和自己比较
      return item.valueName === row.valueName
    }
  })
  if (isRepetition) return AttrItem.value.attrValueList.splice(index, 1)
}
// 将查看模式改为编辑模式
const isSpan = (row: AttrValueItem) => {
  row.isEdit = true;

  // 页面更新的时候 虚拟DOM渲染成真实DOM的过程是异步的  所以想要操作DOM 必须等待真实DOM 渲染完成
  nextTick(() => {  // 真实DOM 渲染完成 回调函数执行
    inputEle.value.focus()  // 自动获取input 焦点
  })
}

// 删除属性值
const removeAttrValueItem = (index: number) => {
  AttrItem.value.attrValueList.splice(index, 1)
}

// 保存时  发送请求 添加属性或者修改属性
const save = async () => {
  // 因为我们在真实的发送数据的数据里面 添加了一个 不需要的值(控制编辑模式还是查看模式) 发请求的时候不需要 所以需要剔除
  AttrItem.value.attrValueList = AttrItem.value.attrValueList.map(item => {
    delete item.isEdit
    return item
  })

  // 当需要添加的数据为空的时候 是不能发请求的 这种数据没有必要
  if (AttrItem.value.attrName == '' || AttrItem.value.attrValueList.length === 0) return ElMessage.error('属性名和属性值不能为空')

  // 发送请求
  try {
    if (AttrItem.value.id) {  // 修改
      await reqAddOrUpdateAttrInfoListAsync(AttrItem.value)
      ElMessage.success('修改成功')
    } else {  // 添加
      await reqAddOrUpdateAttrInfoListAsync(AttrItem.value)
      ElMessage.success('添加成功')
    }
  } catch (e: any) {
    ElMessage.error(AttrItem.value.id ? '修改失败' : '添加失败')
  }
  // 更新数据
  await getAttrList()

  // 显示三级列表的数据
  isAttrOrAddUpdate.value = true
}
// 删除属性
const removeAttr = async (id: number) => {
  try {
    await reqDeleteAttrAsync(id)
    ElMessage.success('删除成功')
    // 更新数据
    await getAttrList()
  } catch (e: any) {
    ElMessage.error(e.message)
  }
}
</script>

<style scoped></style>
